---
id: theming
title: 表格主题
---

## CSS 变量

`<BaseTable />` 中大部分样式都是通过 CSS variables 来定义的。 通过覆盖 CSS variables 的值，可以快速定制出一套新的表格主题。

BaseTable 默认只提供了亮色主题，下面的 WebsiteBaseTable.tsx 展示了在文档网站中，我们是如何实现暗色主题的：

```typescript title="WebsiteBaseTable.tsx"
import useThemeContext from '@theme/hooks/useThemeContext'
import { BaseTable, BaseTableProps } from 'ali-react-table'
import cx from 'classnames'
import React from 'react'
import styled from 'styled-components'

const DarkSupportBaseTable: any = styled(BaseTable)`
  &.dark {
    --bgcolor: #333;
    --header-bgcolor: #45494f;
    --hover-bgcolor: #46484a;
    --header-hover-bgcolor: #606164;
    --highlight-bgcolor: #191a1b;
    --header-highlight-bgcolor: #191a1b;
    --color: #dadde1;
    --header-color: #dadde1;
    --lock-shadow: rgb(37 37 37 / 0.5) 0 0 6px 2px;
    --border-color: #3c4045;
  }
`

export const WebsiteBaseTable = React.forwardRef<BaseTable, BaseTableProps>((props, ref) => {
  const { isDarkTheme } = useThemeContext()

  return <DarkSupportBaseTable ref={ref} className={cx({ dark: isDarkTheme }, props.className)} {...props} />
})
```

## Ant Design 风格

如果你是 antd 用户，可以参考[该文件](https://github.com/alibaba/ali-react-table/blob/master/packages/website/src/assets/AntdBaseTable.tsx)来实现 antd 样式的表格组件。该文件中的 `AntdBaseTable` 提供了以下功能：

- `isLoading={true}` Ant Design 数据加载效果
- `className="bordered"` 带边框样式
- `className="compact"` 紧凑样式
- `className="dark"` 暗色主题

## 主题切换示例

```jsx live
function 主题切换示例() {
  const { dataSource1, operationCol } = assets.biz

  const nameCol = { code: 'name', width: 200, name: '公司名称' }
  const repeats = [
    { code: 'amount', width: 160, align: 'right', name: '金额' },
    { code: 'dept', width: 160, name: '金融机构' },
    { code: 'applier', width: 120, name: '申请人' },
  ]

  function repeat(arr, n) {
    let result = []
    for (let i = 0; i < n; i++) {
      result = result.concat(arr)
    }
    return result
  }

  const [theme, setTheme] = useState('default')

  let Table = BaseTable
  if (theme === 'antd') {
    Table = assets.AntdBaseTable
  } else if (theme === 'hippo') {
    Table = assets.HippoBaseTable
  }

  const { isDarkTheme } = useThemeContext()

  return (
    <div>
      <div>
        <span style={{ marginRight: 24 }}>选择主题：</span>
        <assets.RadioButtonGroup
          value={theme}
          onChange={setTheme}
          dataSource={['default', 'antd', 'hippo'].map((v) => ({ label: v, value: v }))}
        />
      </div>
      <Table
        style={{ marginTop: 12, maxWidth: 800, height: 400, overflow: 'auto' }}
        className={isDarkTheme ? 'dark' : ''}
        dataSource={repeat(dataSource1, 5)}
        columns={[
          {
            name: '序号',
            width: 70,
            align: 'right',
            lock: true,
            getValue(_, rowIndex) {
              return String(rowIndex + 1)
            },
          },
          nameCol,
          ...repeat(repeats, 5),
          operationCol,
        ]}
      />
    </div>
  )
}
```

## 自定义滚动条样式

下面的代码片段展示了如何对表格内的滚动条样式进行定制。

- 纵向滚动条：表格最外层的 div 会包含表格纵向的滚动条，注意下面的 `&` 选择器可以匹配到该 div。
- 横向滚动条：表格内横向滚动条会出现在多个 div 中，组件为这些 div 均设置了 `.art-horizontal-scroll-container` CSS 类名。
  - 注意改变横向滚动条的高度之后，需要相应地为表格设置 `props.stickyScrollHeight={newHeight}`

```jsx
const MyTable = styled(BaseTable)`
  &,
  .art-horizontal-scroll-container {
    ::-webkit-scrollbar {
      width: 10px;
      height: 10px;
    }

    ::-webkit-scrollbar-thumb {
      background: #ccc;
      border: 1px solid #eaeaea;

      &:hover {
        background: #6e6e6e;
      }
    }

    ::-webkit-scrollbar-track {
      background: #eaeaea;
    }
  }
`
```

```jsx live
function 自定义滚动条样式() {
  const { dataSource1 } = assets.biz

  const repeats = [
    { code: 'amount', width: 160, align: 'right', name: '金额' },
    { code: 'dept', width: 160, name: '金融机构' },
    { code: 'applier', width: 120, name: '申请人' },
  ]

  function repeat(arr, n) {
    let result = []
    for (let i = 0; i < n; i++) {
      result = result.concat(arr)
    }
    return result
  }

  return (
    <div>
      <BaseTable
        dataSource={repeat(dataSource1, 5)}
        columns={[{ lock: true, code: 'name', width: 200, name: '公司名称' }, ...repeat(repeats, 5)]}
        stickyScrollHeight={10}
        // 这里的 css 是为了在文档网站中注入样式，实际使用时请按照 styled-components 的常规用法来实现样式覆盖
        css={`
          height: 400px;
          overflow: auto;

          &,
          .art-horizontal-scroll-container {
            ::-webkit-scrollbar {
              width: 10px;
              height: 10px;
            }

            ::-webkit-scrollbar-thumb {
              background: #ccc;
              border: 1px solid #eaeaea;

              &:hover {
                background: #6e6e6e;
              }
            }

            ::-webkit-scrollbar-track {
              background: #eaeaea;
            }
          }
        `}
      />
    </div>
  )
}
```

ali-react-table 也通过 Classes 对象暴露了相关 div 的类名，推荐使用下面的方式来引用：

- `Classes.artTableWrapper` 表格最外层 div 的 CSS 类名
- `Classes.horizontalScrollContainer` 表格内出现横向滚动条 div 的 CSS 类名
